#include <iostream>
#include <fstream>
#include <vector>
#include <unordered_map>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <termios.h>
#include <unistd.h>
#include <sys/ioctl.h>

using namespace std;

// macOS 类型定义
typedef unsigned short WORD;
typedef void* HANDLE;

// macOS 控制台颜色定义
#define FOREGROUND_BLUE      0x0001
#define FOREGROUND_GREEN     0x0002
#define FOREGROUND_RED       0x0004
#define FOREGROUND_INTENSITY 0x0008
#define BACKGROUND_BLUE      0x0010
#define BACKGROUND_GREEN     0x0020
#define BACKGROUND_RED       0x0040
#define BACKGROUND_INTENSITY 0x0080

// macOS 终端函数实现
int _getch() {
    struct termios oldt, newt;
    int ch;
    tcgetattr(STDIN_FILENO, &oldt);
    newt = oldt;
    newt.c_lflag &= ~(ICANON | ECHO);
    tcsetattr(STDIN_FILENO, TCSANOW, &newt);
    ch = getchar();
    tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
    return ch;
}

int _kbhit() {
    static const int STDIN = 0;
    static bool initialized = false;
    if (!initialized) {
        termios term;
        tcgetattr(STDIN, &term);
        term.c_lflag &= ~ICANON;
        tcsetattr(STDIN, TCSANOW, &term);
        setbuf(stdin, NULL);
        initialized = true;
    }
    int bytesWaiting;
    ioctl(STDIN, FIONREAD, &bytesWaiting);
    return bytesWaiting;
}

void SetConsoleTextAttribute(HANDLE hConsole, WORD wAttributes) {
    // macOS 终端颜色代码
    if (wAttributes & BACKGROUND_BLUE) {
        cout << "\033[44;37m"; // 蓝底白字
    } else if (wAttributes & BACKGROUND_RED) {
        cout << "\033[41;37m"; // 红底白字
    } else if (wAttributes & BACKGROUND_GREEN) {
        cout << "\033[42;37m"; // 绿底白字
    } else if (wAttributes & FOREGROUND_GREEN) {
        cout << "\033[32m"; // 绿色
    } else if (wAttributes & FOREGROUND_RED) {
        cout << "\033[31m"; // 红色
    } else if (wAttributes & FOREGROUND_INTENSITY) {
        cout << "\033[1m"; // 加亮
    } else {
        cout << "\033[0m"; // 重置
    }
}

void system_clear() {
    cout << "\033[2J\033[1;1H"; // 清屏并移动光标到左上角
}

// 全局变量
size_t memory_size;
int g_cell_init_value = 0;
bool g_show_warnings = true;
bool g_show_steps = false;
bool g_show_code = false;
bool g_debug_mode = false;
bool g_auto_wrap = false;
int g_wrap_column = 80;
string g_code;
int memory_show_size = 16;

// 函数声明
void show_editor(const string& code, size_t cursor_pos);
void editor();
void execute(char* file);
void settings();
void load_code_from_file(string& code, size_t& cursor);
void save_code_to_file(const string& code);
void show_help();
int read_key();
bool handle_colon_command(const string& cmd, string& code, size_t& cursor);

// ===================== 读取键序列 =====================
int read_key() {
    int ch = _getch();
    
    if (ch == 27) { // ESC
        if (_kbhit()) {
            int seq1 = _getch();
            if (seq1 == 91) { // '['
                if (_kbhit()) {
                    int seq2 = _getch();
                    // 方向键
                    if (seq2 == 65) return 256 + 1; // 上
                    if (seq2 == 66) return 256 + 2; // 下  
                    if (seq2 == 67) return 256 + 3; // 右
                    if (seq2 == 68) return 256 + 4; // 左
                }
            }
        } else {
            return 27; // 单独的 ESC
        }
    }
    
    return ch;
}

// ===================== 显示帮助信息 =====================
void show_help() {
    system_clear();
    printf("=== Brainfuck IDE 帮助 ===\n\n");
    printf("编辑命令:\n");
    printf("  方向键    - 移动光标\n");
    printf("  BKSP/DEL  - 删除字符\n");
    printf("  Enter     - 换行\n");
    printf("  Tab       - 插入4个空格\n");
    printf("  普通字符  - 插入代码\n\n");
    
    printf("功能命令 (输入冒号进入命令模式):\n");
    printf("  :s        - 保存代码\n");
    printf("  :l        - 加载代码\n");
    printf("  :r        - 运行代码\n");
    printf("  :d        - 调试运行\n");
    printf("  :o        - 设置\n");
    printf("  :q        - 退出\n");
    printf("  :h        - 显示帮助\n");
    printf("  :c        - 清空代码\n\n");
    
    printf("按任意键返回编辑器...");
    _getch();
}

// ===================== 处理冒号命令 =====================
bool handle_colon_command(const string& cmd, string& code, size_t& cursor) {
    if (cmd == ":s" || cmd == ":w") {
        save_code_to_file(code);
        return true;
    }
    else if (cmd == ":l" || cmd == ":load") {
        load_code_from_file(code, cursor);
        return true;
    }
    else if (cmd == ":r" || cmd == ":run") {
        execute(nullptr);
        printf("按任意键返回编辑器...");
        _getch();
        return true;
    }
    else if (cmd == ":d" || cmd == ":debug") {
        g_debug_mode = true;
        execute(nullptr);
        g_debug_mode = false;
        printf("按任意键返回编辑器...");
        _getch();
        return true;
    }
    else if (cmd == ":o" || cmd == ":options") {
        settings();
        return true;
    }
    else if (cmd == ":q" || cmd == ":quit") {
        printf("\n确定要退出吗？(y/n): ");
        int confirm = _getch();
        if (confirm == 'y' || confirm == 'Y') {
            exit(0);
        }
        return true;
    }
    else if (cmd == ":h" || cmd == ":help") {
        show_help();
        return true;
    }
    else if (cmd == ":c" || cmd == ":clear") {
        code.clear();
        cursor = 0;
        return true;
    }
    
    return false;
}

// ===================== 编辑器显示 =====================
void show_editor(const string& code, size_t cursor_pos) {
    system_clear();
    printf("Brainfuck 编辑器 - macOS 版本\n");
    printf("输入 : 进入命令模式，然后输入:\n");
    printf("  :s 保存  :l 加载  :r 运行  :d 调试  :o 设置  :q 退出  :h 帮助\n");
    printf("编辑: 方向键移动光标，直接输入代码，Tab插入空格\n\n");

    vector<string> lines;
    vector<bool> is_manual_newline;
    string cur_line;
    int col_count = 0;
    size_t code_pos = 0;
    
    for (size_t i = 0; i < code.size(); ++i, ++code_pos) {
        char c = code[i];
        if (c == '\n') {
            cur_line += c;
            lines.push_back(cur_line);
            is_manual_newline.push_back(true);
            cur_line.clear();
            col_count = 0;
        }
        else {
            cur_line += c;
            col_count++;
            if (g_auto_wrap && col_count >= g_wrap_column) {
                lines.push_back(cur_line);
                is_manual_newline.push_back(false);
                cur_line.clear();
                col_count = 0;
            }
        }
    }
    if (!cur_line.empty() || code.empty()) {
        lines.push_back(cur_line);
        is_manual_newline.push_back(true);
    }

    size_t line = 0, col = 0, pos = 0;
    for (size_t i = 0; i < lines.size(); ++i) {
        if (cursor_pos < pos + lines[i].size()) {
            line = i;
            col = cursor_pos - pos;
            break;
        }
        pos += lines[i].size();
    }

    vector<int> bracket_stack;
    vector<bool> unmatched(code.size(), false);
    vector<int> unmatched_indices;
    for (size_t i = 0; i < code.size(); ++i) {
        if (code[i] == '[') {
            bracket_stack.push_back((int)i);
        }
        else if (code[i] == ']') {
            if (!bracket_stack.empty()) {
                bracket_stack.pop_back();
            }
            else {
                unmatched[i] = true;
                unmatched_indices.push_back((int)i);
            }
        }
    }
    for (int idx : bracket_stack) {
        unmatched[idx] = true;
        unmatched_indices.push_back(idx);
    }
    
    vector<bool> highlight_green(code.size(), false);
    for (int idx : unmatched_indices) {
        for (int offset = -3; offset <= 3; ++offset) {
            int pos = idx + offset;
            if (pos >= 0 && pos < (int)code.size() && !unmatched[pos]) {
                highlight_green[pos] = true;
            }
        }
    }

    code_pos = 0;
    size_t line_number = 1;
    for (size_t i = 0; i < lines.size(); ++i) {
        if (is_manual_newline[i]) {
            printf("%3zu ", line_number++);
        }
        else {
            printf("    ");
        }
        for (size_t j = 0; j < lines[i].size(); ++j, ++code_pos) {
            if (code_pos == cursor_pos) {
                SetConsoleTextAttribute(nullptr, BACKGROUND_BLUE | FOREGROUND_INTENSITY);
            }
            else if (unmatched[code_pos]) {
                SetConsoleTextAttribute(nullptr, BACKGROUND_RED | FOREGROUND_INTENSITY);
            }
            else if (highlight_green[code_pos]) {
                SetConsoleTextAttribute(nullptr, BACKGROUND_GREEN);
            }
            else if (strchr("+-<>[],.", lines[i][j])) {
                SetConsoleTextAttribute(nullptr, FOREGROUND_GREEN | FOREGROUND_INTENSITY);
            }
            else {
                SetConsoleTextAttribute(nullptr, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
            }
            
            if (lines[i][j] == '\n') {
                printf("\\n");
            }
            else {
                printf("%c", lines[i][j]);
            }
            SetConsoleTextAttribute(nullptr, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
        }
        if (code_pos == cursor_pos && col == lines[i].size()) {
            SetConsoleTextAttribute(nullptr, BACKGROUND_BLUE | FOREGROUND_INTENSITY);
            printf(" ");
            SetConsoleTextAttribute(nullptr, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
        }
        printf("\n");
    }
    printf("\n光标位置：第 %zu 行，第 %zu 列\n", line + 1, col + 1);

    if (!unmatched_indices.empty()) {
        SetConsoleTextAttribute(nullptr, FOREGROUND_RED | FOREGROUND_INTENSITY);
        printf("警告：括号不匹配！\n");
        SetConsoleTextAttribute(nullptr, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
    }
}

// ===================== 编辑器主循环 =====================
void editor() {
    g_code = "";
    size_t cursor = 0;
    
    show_editor(g_code, cursor);
    
    while (true) {
        int ch = read_key();
        
        // 检测是否输入了冒号（进入命令模式）
        if (ch == ':') {
            // 进入命令模式
            string command = ":";
            system_clear();
            printf("命令模式 - 输入命令后按 Enter\n");
            printf("当前命令: :_\n");
            
            // 读取命令
            while (true) {
                int cmd_ch = _getch();
                if (cmd_ch == 13) { // Enter
                    break;
                }
                else if (cmd_ch == 27) { // ESC
                    command.clear();
                    break;
                }
                else if (cmd_ch == 8 || cmd_ch == 127) { // BKSP
                    if (!command.empty()) {
                        command.pop_back();
                    }
                }
                else if (cmd_ch >= 32 && cmd_ch <= 126) {
                    command += (char)cmd_ch;
                }
                
                system_clear();
                printf("命令模式 - 输入命令后按 Enter\n");
                printf("当前命令: %s_\n", command.c_str());
            }
            
            // 执行命令
            if (!command.empty() && command != ":") {
                if (!handle_colon_command(command, g_code, cursor)) {
                    printf("未知命令: %s\n按任意键继续...", command.c_str());
                    _getch();
                }
            }
            
            show_editor(g_code, cursor);
            continue;
        }
        
        // 正常编辑模式（原有代码保持不变）
        else if (ch >= 256 + 1 && ch <= 256 + 4) { // 方向键
            if (ch == 256 + 3 && cursor < g_code.size()) cursor++; // 右
            if (ch == 256 + 4 && cursor > 0) cursor--; // 左
        }
        else if (ch == 8 || ch == 127) { // BKSP
            if (cursor > 0) {
                g_code.erase(cursor - 1, 1);
                cursor--;
            }
        }
        else if (ch == 13) { // Enter
            g_code.insert(cursor, 1, '\n');
            cursor++;
        }
        else if (ch >= 32 && ch <= 126) { // 可见字符
            g_code.insert(cursor, 1, (char)ch);
            cursor++;
        }
        else if (ch == 9) { // Tab
            g_code.insert(cursor, 4, ' ');
            cursor += 4;
        }
        else if (ch == 27) { // ESC - 显示帮助
            show_help();
            show_editor(g_code, cursor);
            continue;
        }
        
        show_editor(g_code, cursor);
    }
}

// ===================== 解释器 =====================
void execute(char* file) {
    system_clear();
    vector<unsigned char> memory(memory_size, g_cell_init_value);
    auto cur = memory.begin();
    string program;
    
    if (file) {
        ifstream code(file);
        if (!code.is_open()) {
            cout << "无法打开文件: " << file << endl;
            return;
        }
        program.assign((istreambuf_iterator<char>(code)), istreambuf_iterator<char>());
    }
    else {
        program = g_code;
    }

    string filtered;
    for (char c : program) {
        if (c != '\r' && c != '\n' && c != '\t' && c != ' ') {
            filtered += c;
        }
    }
    program = filtered;

    printf("已加载代码:\n%s\n\n", program.c_str());
    printf("代码长度: %zu\n", program.size());
    printf("提示: 运行过程中按 ESC 键可停止执行\n\n");

    size_t pc = 0;
    int cnt = 1;
    unordered_map<size_t, size_t> loop_map;
    vector<size_t> stack;
    
    for (size_t i = 0; i < program.size(); ++i) {
        if (program[i] == '[') stack.push_back(i);
        else if (program[i] == ']') {
            if (stack.empty()) {
                cout << "字符 " << (i + 1) << ": 程序中有多余的 ']' " << endl;
                return;
            }
            size_t open = stack.back();
            stack.pop_back();
            loop_map[open] = i;
            loop_map[i] = open;
        }
    }
    if (!stack.empty()) {
        cout << "字符 " << (stack.back() + 1) << ": 程序中有多余的 '[' " << endl;
        return;
    }

    bool user_stopped = false;
    
    while (pc < program.size() && !user_stopped) {
        if (_kbhit()) {
            int ch = _getch();
            if (ch == 27) {
                user_stopped = true;
                printf("\n\n用户中断执行！\n");
                break;
            }
        }
        
        char now = program[pc];
        if (g_show_steps) {
            printf("步骤 %d: '%c' | 指针: %zd | 值: %d\n", cnt, now, cur - memory.begin(), *cur);
        }
        if (g_show_code) {
            printf("当前代码: ");
            for (size_t i = 0; i < program.size(); ++i) {
                if (i == pc) {
                    SetConsoleTextAttribute(nullptr, BACKGROUND_BLUE | FOREGROUND_INTENSITY);
                    printf("%c", program[i]);
                    SetConsoleTextAttribute(nullptr, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
                }
                else {
                    printf("%c", program[i]);
                }
            }
            printf("\n");
        }

        switch (now) {
            case '+': ++(*cur); break;
            case '-': --(*cur); break;
            case '<': 
                if (cur == memory.begin()) {
                    cout << "步骤 " << cnt << ": 指针越界" << endl;
                    break;
                }
                --cur;
                break;
            case '>':
                if (++cur == memory.end()) {
                    cout << "步骤 " << cnt << ": 指针越界" << endl;
                    --cur;
                    break;
                }
                break;
            case '.':
                cout << static_cast<char>(*cur);
                break;
            case ',':
            {
                char input;
                cin >> input;
                *cur = input;
                break;
            }
            case '[':
                if (*cur == 0) pc = loop_map[pc];
                break;
            case ']':
                if (*cur != 0) pc = loop_map[pc];
                break;
            default:
                if (now != ' ' && now != '\t' && g_show_warnings) {
                    cout << "步骤 " << cnt << ": 非法字符 '" << now << "'" << endl;
                }
                break;
        }
        ++pc;
        ++cnt;
        
        if (g_show_steps) {
            if (_kbhit()) {
                int ch = _getch();
                if (ch == 27) {
                    user_stopped = true;
                    printf("\n\n用户中断执行！\n");
                    break;
                }
            }
            printf("按任意键继续...");
            _getch();
            printf("\n");
        }
    }
    
    if (!user_stopped) {
        printf("\n\n程序执行完成！\n");
    }
}

// ===================== 设置界面 =====================
void settings() {
    system_clear();
    printf("=== 设置 ===\n\n");
    printf("内存大小: %zu\n", memory_size);
    printf("单元初值: %d\n", g_cell_init_value);
    printf("显示警告: %s\n", g_show_warnings ? "是" : "否");
    printf("显示步骤: %s\n", g_show_steps ? "是" : "否");
    printf("显示代码: %s\n", g_show_code ? "是" : "否");
    printf("调试模式: %s\n", g_debug_mode ? "是" : "否");
    printf("\n按任意键返回...");
    _getch();
}

// ===================== 文件操作 =====================
void save_code_to_file(const string& code) {
    printf("\n请输入要保存的文件名: ");
    string filename;
    cin >> filename;
    ofstream file(filename);
    if (file) {
        file << code;
        printf("代码已保存到 %s\n", filename.c_str());
    } else {
        printf("无法保存文件！\n");
    }
    printf("按任意键继续...");
    _getch();
}

void load_code_from_file(string& code, size_t& cursor) {
    printf("\n请输入要加载的文件名: ");
    string filename;
    cin >> filename;
    ifstream file(filename);
    if (file) {
        code.assign((istreambuf_iterator<char>(file)), istreambuf_iterator<char>());
        cursor = code.size();
        printf("代码已从 %s 加载\n", filename.c_str());
    } else {
        printf("无法加载文件！\n");
    }
    printf("按任意键继续...");
    _getch();
}

// ===================== 主函数 =====================
int main() {
    cout<<"还没写完啊，大概在国庆结束之前写得完";
    // memory_size = 30000;
    // printf("Brainfuck IDE - macOS 版本\n");
    // printf("按任意键进入编辑器...");
    // _getch();
    // editor();
    return 0;
}